package com.entmanage.base.oa.service.impl;

import java.util.HashSet;
import java.util.List;

import com.entmanage.base.oa.domain.OaOvertimeApply;
import com.entmanage.common.core.domain.entity.SysUser;
import com.entmanage.common.utils.DateUtils;
import com.entmanage.system.service.ISysUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import com.entmanage.common.utils.SecurityUtils;
import java.util.ArrayList;
import java.util.Set;
import java.util.stream.Collectors;

import com.entmanage.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.entmanage.base.oa.domain.OaReimbursementDetail;
import com.entmanage.base.oa.mapper.OaReimbursementApplyMapper;
import com.entmanage.base.oa.domain.OaReimbursementApply;
import com.entmanage.base.oa.service.IOaReimbursementApplyService;

/**
 * OA报销申请主Service业务层处理
 *
 * @author lsq
 * @date 2025-09-25
 */
@Service
public class OaReimbursementApplyServiceImpl implements IOaReimbursementApplyService
{
    @Autowired
    private OaReimbursementApplyMapper oaReimbursementApplyMapper;

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private ISysUserService sysUserService;

    private static final Logger log = LoggerFactory.getLogger(OaLeaveApplyServiceImpl.class);

    /**
     * 查询OA报销申请主
     *
     * @param id OA报销申请主主键
     * @return OA报销申请主
     */
    @Override
    public OaReimbursementApply selectOaReimbursementApplyById(Long id)
    {
        return oaReimbursementApplyMapper.selectOaReimbursementApplyById(id);
    }

    /**
     * 查询OA报销申请主列表
     *
     * @param oaReimbursementApply OA报销申请主
     * @return OA报销申请主
     */
    @Override
    public List<OaReimbursementApply> selectOaReimbursementApplyList(OaReimbursementApply oaReimbursementApply)
    {
        return oaReimbursementApplyMapper.selectOaReimbursementApplyList(oaReimbursementApply);
    }

    /**
     * 新增OA报销申请主
     *
     * @param oaReimbursementApply OA报销申请主
     * @return 结果
     */
    @Transactional
    @Override
    public int insertOaReimbursementApply(OaReimbursementApply oaReimbursementApply)
    {
        // 保存用户和部门ID
        oaReimbursementApply.setUserId(SecurityUtils.getUserId());
        oaReimbursementApply.setDeptId(SecurityUtils.getDeptId());
        oaReimbursementApply.setCreateTime(DateUtils.getNowDate());
    oaReimbursementApply.setCreateBy(SecurityUtils.getUsername());
        int rows = oaReimbursementApplyMapper.insertOaReimbursementApply(oaReimbursementApply);
        // ✅ 此时 ID 已生成
        System.out.println("Generated ID: " + oaReimbursementApply.getId());
        insertOaReimbursementDetail(oaReimbursementApply);
        return rows;
    }

    /**
     * 修改OA报销申请主
     *
     * @param oaReimbursementApply OA报销申请主
     * @return 结果
     */
    @Transactional
    @Override
    public int updateOaReimbursementApply(OaReimbursementApply oaReimbursementApply)
    {
        oaReimbursementApply.setUpdateTime(DateUtils.getNowDate());
    oaReimbursementApply.setUpdateBy(SecurityUtils.getUsername());
        oaReimbursementApplyMapper.deleteOaReimbursementDetailByApplyId(oaReimbursementApply.getId());
        insertOaReimbursementDetail(oaReimbursementApply);
        return oaReimbursementApplyMapper.updateOaReimbursementApply(oaReimbursementApply);
    }

    /**
     * 批量删除OA报销申请主
     *
     * @param ids 需要删除的OA报销申请主主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteOaReimbursementApplyByIds(Long[] ids)
    {
        oaReimbursementApplyMapper.deleteOaReimbursementDetailByApplyIds(ids);
        return oaReimbursementApplyMapper.deleteOaReimbursementApplyByIds(ids);
    }

    /**
     * 删除OA报销申请主信息
     *
     * @param id OA报销申请主主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteOaReimbursementApplyById(Long id)
    {
        oaReimbursementApplyMapper.deleteOaReimbursementDetailByApplyId(id);
        return oaReimbursementApplyMapper.deleteOaReimbursementApplyById(id);
    }

    /**
     * 新增OA报销申请-费用明细信息
     *
     * @param oaReimbursementApply OA报销申请主对象
     */
    public void insertOaReimbursementDetail(OaReimbursementApply oaReimbursementApply)
    {
        List<OaReimbursementDetail> oaReimbursementDetailList = oaReimbursementApply.getOaReimbursementDetailList();
        Long id = oaReimbursementApply.getId();
        Long userId = oaReimbursementApply.getUserId();     // 👈 从主表获取
        Long deptId = oaReimbursementApply.getDeptId();     // 👈 从主表获取
        if (StringUtils.isNotNull(oaReimbursementDetailList))
        {
            List<OaReimbursementDetail> list = new ArrayList<OaReimbursementDetail>();
            for (OaReimbursementDetail oaReimbursementDetail : oaReimbursementDetailList)
            {
                oaReimbursementDetail.setApplyId(id);
                oaReimbursementDetail.setUserId(userId);
                oaReimbursementDetail.setDeptId(deptId);
                list.add(oaReimbursementDetail);
            }
            if (list.size() > 0)
            {
                oaReimbursementApplyMapper.batchOaReimbursementDetail(list);
            }
        }
    }

    @Override
    @Async
    public void sendReimbursementApprovalEmail(
            List<Long> approverIds,
            List<Long> ccIds,
            String reimbursementType,
            String reason,
            String totalAmount,
            String applicantName) {

        log.info("【开始发送报销审批邮件】类型={}，金额={}，审核人IDs={}，抄送IDs={}",
                reimbursementType,
                totalAmount,
                approverIds != null ? approverIds : "无",
                ccIds != null ? ccIds : "无");

        // 参数基本校验
        if (StringUtils.isEmpty(reason)) {
            log.warn("邮件发送中止：报销事由为空");
            return;
        }
        if (StringUtils.isEmpty(reimbursementType)) {
            log.warn("邮件发送中止：报销类型为空");
            return;
        }
        if (StringUtils.isEmpty(totalAmount)) {
            log.warn("邮件发送中止：报销金额为空");
            return;
        }

        Set<String> toEmails = new HashSet<>();
        Set<String> ccEmails = new HashSet<>();

        // 查询审核人邮箱
        if (approverIds != null && !approverIds.isEmpty()) {
            List<SysUser> approvers = sysUserService.selectUserByIds(approverIds);
            toEmails.addAll(filterValidEmails(approvers, "审核人"));
        }

        // 查询抄送人邮箱
        if (ccIds != null && !ccIds.isEmpty()) {
            List<SysUser> ccs = sysUserService.selectUserByIds(ccIds);
            ccEmails.addAll(filterValidEmails(ccs, "抄送人"));
        }

        if (toEmails.isEmpty() && ccEmails.isEmpty()) {
            log.warn("未找到任何有效邮箱地址，终止发送报销邮件");
            return;
        }

        // 构建邮件主题和正文
        String subject = "[报销申请] " + applicantName + " 申请报销 - " + reimbursementType;
        String content = String.format(
                "您好：\n\n" +
                        "%s 提交了一条报销申请。\n\n" +
                        "报销类型：%s\n" +
                        "报销金额：%s 元\n" +
                        "报销事由：%s\n\n" +
                        "请登录OA系统进行查看或审批。\n\n" +
                        "—— OA系统自动通知",
                applicantName != null ? applicantName : "某员工",
                reimbursementType,
                totalAmount,
                StringUtils.isEmpty(reason) ? "无" : reason
        );

        try {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom("1911708828@qq.com"); // 建议配置为 application.yml 中的 mail.from
            message.setSubject(subject);
            message.setText(content);

            // 发送给审批人
            if (!toEmails.isEmpty()) {
                message.setTo(toEmails.toArray(new String[0]));
                javaMailSender.send(message);
                toEmails.forEach(email -> log.info("报销审批邮件已发送至审核人: {}", email));
            }

            // 单独发送给抄送人（避免暴露审批人邮箱给抄送人）
            if (!ccEmails.isEmpty()) {
                SimpleMailMessage ccMessage = new SimpleMailMessage(message);
                ccMessage.setTo(ccEmails.toArray(new String[0]));
                javaMailSender.send(ccMessage);
                ccEmails.forEach(email -> log.info("报销审批邮件已抄送至: {}", email));
            }

            log.info("【报销审批邮件发送完成】共发送 {} 封邮件", toEmails.size() + ccEmails.size());

        } catch (Exception e) {
            log.error("发送报销审批邮件时发生异常", e);
        }
    }

    /**
     * 从 SysUser 列表中提取非空且格式有效的邮箱
     */
    private Set<String> filterValidEmails(List<SysUser> users, String role) {
        return users.stream()
                .filter(user -> user != null && StringUtils.isNotEmpty(user.getEmail()))
                .map(SysUser::getEmail)
                .collect(Collectors.toSet());
    }

    @Override
    public List<OaReimbursementApply> selectByApproverId(Long approverId) {
        return oaReimbursementApplyMapper.selectByApproverId(approverId);
    }

    @Override
    public List<OaReimbursementApply> selectByCcId(Long currentUserId) {
        return oaReimbursementApplyMapper.selectByCcId(currentUserId);
    }

}
